package com.engineering.elink.service.impl;

import java.util.Date;
import java.util.HashMap;
import java.util.Map;

import org.apache.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.engineering.elink.co.PersonMuitlTypeCo;
import com.engineering.elink.co.PersonUpdateCo;
import com.engineering.elink.co.UserCo;
import com.engineering.elink.common.CoinRuleEnum;
import com.engineering.elink.common.Constant;
import com.engineering.elink.common.HessionInfluenceEnum;
import com.engineering.elink.dao.PersonCustomMapper;
import com.engineering.elink.dao.PersonMapper;
import com.engineering.elink.dao.TokenAuthenticationMapper;
import com.engineering.elink.dao.UserMapper;
import com.engineering.elink.domain.Person;
import com.engineering.elink.domain.User;
import com.engineering.elink.service.CoinBalanceService;
import com.engineering.elink.service.PersonService;
import com.engineering.elink.service.RedisService;
import com.engineering.elink.service.VerificationService;
import com.engineering.elink.util.ConfigUtil;
import com.engineering.elink.util.global.TokenExpireTime;
import com.engineering.elink.util.io.ImgUtil;
import com.engineering.elink.util.token.MD5Util;
import com.engineering.elink.util.token.TokenGenerator;
import com.engineering.elink.util.tool.UUIDUtil;
import com.engineering.elink.util.verify.VerifyCodeUtils;

@Service
public class PersonServiceImpl implements PersonService {
	private final static String defaultLogo = ConfigUtil.getValue("default_logo");
	@Autowired
	private RedisService redisService;
	@Autowired
	private UserMapper userMapper;
	@Autowired
	private TokenAuthenticationMapper tokenAuthenticationMapper;
	@Autowired
	private PersonMapper personMapper;
	@Autowired
	private VerificationService verificationService;
	@Autowired
	private PersonCustomMapper  personCustomMapper;
	@Autowired
	private CoinBalanceService coinBalanceService;
	
	@Override
	public void personRegWithVerifyCode(String verifyToken, String verifyCode) {
		System.out.println("##########"+verifyToken);
		Map<String, Object> map = new HashMap<String, Object>();
		Map<String, Object> dataMap = new HashMap<String, Object>();
		dataMap.put("verifyCode", verifyCode);
		map.put("data", dataMap);
		// status == 1 发送验证码 第一步
		map.put("status", 1);
		map.put("type", Constant.personRegCache);
		redisService.putSeedObjectMap(Constant.redisCommonCache, verifyToken,
				map, Constant.personRegCacheOneStepValidTime);
	}

	@SuppressWarnings("unchecked")
	@Override
	public boolean personRegWithSendPhoneCode(String phone, String verifyToken,
			String verifyCode) {
		Map<String, Object> map = (Map<String, Object>) redisService.getObjectBySeed(Constant.redisCommonCache, verifyToken);
		System.out.println("##########"+verifyToken);
		System.out.println("map="+map.toString());
		if (map == null|| !map.containsKey("object")|| map.get("object") == null || !((Map<String, Object>) map.get("object")).containsKey("status")
				|| !((Map<String, Object>) map.get("object"))	.containsKey("type")
				|| !((Map<String, Object>) map.get("object")).containsKey("data")) {
			return false;
		}
		Map<String, Object> tmpMap = (Map<String, Object>) map.get("object");
		int status = (int) tmpMap.get("status");
		int type = (int) tmpMap.get("type");
		tmpMap = (Map<String, Object>) tmpMap.get("data");
		String verifyCodeInRedis = (String) tmpMap.get("verifyCode");
		System.out.println(map.toString());
		System.out.println(((Map<String, Object>) ((Map<String, Object>) map.get("object")).get("data")).get("verifyCode"));
		if ((status == 1 || status == 2)  && type == Constant.personRegCache && verifyCode.equals(verifyCodeInRedis)) {
			// 发送验证码
			verifyCode = VerifyCodeUtils.generateNumberCode(4);
			// todo
			System.out.println("手机短信验证码为=" + verifyCode);
			verificationService.sendPhoneCode(phone, verifyCode);
			map.clear();
			Map<String, Object> dataMap = new HashMap<String, Object>();
			dataMap.put("phone", phone);
			dataMap.put("verifyCode", verifyCode);
			map.put("data", dataMap);
			// status == 2 发送短信 第二步
			map.put("status", 2);
			map.put("type", Constant.personRegCache);
			redisService.putSeedObjectMap(Constant.redisCommonCache,verifyToken, map, Constant.personRegCacheThreeStepValidTime);
			return true;
		}
		return false;
	}

	@SuppressWarnings("unchecked")
	@Override
	public Map<String, Object> personRegWithBaseInfo(String email, String phone,String passwd, String verifyToken, String verifyCode) {
		Map<String, Object> map = (Map<String, Object>) redisService.getObjectBySeed(Constant.redisCommonCache, verifyToken);
		if (map == null
				|| !map.containsKey("object")
				|| map.get("object") == null
				|| !((Map<String, Object>) map.get("object")).containsKey("status")
				|| !((Map<String, Object>) map.get("object")).containsKey("type")
				|| !((Map<String, Object>) map.get("object")).containsKey("data"))
			return null;
		Map<String, Object> tmpMap = (Map<String, Object>) map.get("object");
		int status = (int) tmpMap.get("status");
		int type = (int) tmpMap.get("type");
		tmpMap = (Map<String, Object>) tmpMap.get("data");
		String verifyCodeInRedis = (String) tmpMap.get("verifyCode");
		String phoneInRedis = (String) tmpMap.get("phone");
		if ((status == 2 || status == 3)  && type == Constant.personRegCache && verifyCode.equals(verifyCodeInRedis)
				&& phone.equals(phoneInRedis)) {
			redisService.delObjectBySeed(Constant.redisCommonCache, verifyToken);
			// 生成新用户数据 用户ID和密码
			UserCo userCo = new UserCo();
			String userId = UUIDUtil.getUUID();
			userCo.setUserId(userId);
			userCo.setPasswd(MD5Util.getMD5String(passwd));
			userCo.setPhone(phone);
			userCo.setEmail(email);
			userCo.setCreateTime(new Date());
			userCo.setUserType(Constant.personUserType);
			userCo.setLevelId(1);
			userCo.setCoinValue(Integer.parseInt(ConfigUtil.getValue("register_coin")));	//注册送积分
			userMapper.insertSelective(userCo);

			// 将用户令牌存入缓存
			String seed = TokenGenerator.getSeed(userCo.getUserId());
			String authToken = TokenGenerator.getToken();
			map.put("authToken", authToken);
			map.put("userId", userCo.getUserId());
			redisService.putSeedObjectMap(Constant.tokenAuthenticationCache,seed, map, Constant.validTime);
			// 将用户令牌存入持久化
			System.out.println("###########7");
			map.clear();
			map.put("seed", seed);
			map.put("userId", userCo.getUserId());
			map.put("expireTimeDiff", TokenExpireTime.AuthTokenTTL);
			map.put("token", authToken);
			tokenAuthenticationMapper.insertAuthToken(map);
			
			System.out.println("###########7");
			map.clear();
			map.put("seed", seed);
			map.put("authToken", authToken);
			
			// 将用户信息插入附表
			Person person = new Person();
			person.setPersonId(userId);
			person.setUserId(userId);
			person.setLogo(defaultLogo);
			
			//设置默认昵称
			person.setNickname(phone.substring(0, 3)+"****"+phone.substring(7));
			personMapper.insertSelective(person);
			//更新积分
			coinBalanceService.modifyCoin(userId, CoinRuleEnum.REGISTER.getIndex(), 0, userId, "");
			return map;
		}
		return null;
	}

	@Override
	public Map<String, Object> login(String account, String passwd) {
		passwd = MD5Util.getMD5String(passwd);
		User user = userMapper.selectByAccountAndPasswd(Constant.personUserType, account, passwd);
		if (user != null) {
			Map<String, Object> map = new HashMap<String, Object>();
			String seed = TokenGenerator.getSeed(user.getUserId());
			String authToken = TokenGenerator.getToken();
			map.put("seed", seed);
			map.put("authToken", authToken);
			map.put("user", user);
			//添加影响值
			try{
				coinBalanceService.modifyInfluenceValue("", HessionInfluenceEnum.LOGIN.getIndex(), user.getUserId());
			}catch (Exception e){
				  Logger logger = Logger.getLogger(PersonServiceImpl.class);
				  logger.info("远程添加登录获取影响值失败"+e);
			}
			return map;
		}
		return null;
	}

	@Override
	public boolean modifyMutilType(PersonMuitlTypeCo personMuitlTypeCo) {
		personMapper.updateByUserIdFromPersonMuitlTypeCoSelective(personMuitlTypeCo);
		return true;
	}

	@Override
	public Map<String, Object> getPersonInfo(String userId) {
		return personMapper.selectPersonInfoByUserId(userId);
	}

	@Override
	public boolean modifyPersonInfo(PersonUpdateCo personUpdateCo) {
		Person person = personMapper.selectByUserId(personUpdateCo.getUserId());
		if (person.getLogo()== null || ( person.getLogo()!= null && !person.getLogo().equals(personUpdateCo.getLogo())) ) {
			String fileName = UUIDUtil.getUUID() + ".png";
			String filePath = Constant.imageFilePath + fileName;
			System.out.println("beginning transcode base64 to localImage");
			ImgUtil.GenerateImage(personUpdateCo.getLogo(), filePath);
			System.out.println("transcode finished");
			personUpdateCo.setLogo(Constant.webPicPath+"/upload/file/image/"+fileName);
		}
		personMapper.updateByUserIdFromPersonSelective(personUpdateCo);
		return true;
	}

	@Override
	public Map<String, Object> getBasePersonInfoByMine(String userId) {
		return personMapper.selectBasePersonInfoByMine(userId);
	}

	@Override
	public Map<String, Object> getBasePersonInfoByOther(String userId,String otherUserId) {
		return personMapper.selectBasePersonInfoByOther(userId, otherUserId);
	}

	@Override
	public Person getPersonAllInfo(String userId) {
		return personMapper.selectByUserId(userId);
	}
}
